package com.ruoyi.common.encrypt;

import com.ruoyi.common.utils.AESUtils;
import com.ruoyi.common.utils.ToolUtils;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 加解密 类型处理器
 */
public class EncryptHandler implements TypeHandler<String> {

    // AES key
    private static final String DEFAULT_KEY = "mj/Pc8haRoYUFcxG2aFVcQ==";

    // 设置参数时的加密操作（用于插入数据）
    @Override
    public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        // 执行加密逻辑，将密文写入预编译语句
        if (parameter != null) {
            ps.setString(i, AESUtils.encrypt(DEFAULT_KEY, parameter));
        } else {
            ps.setNull(i, jdbcType.TYPE_CODE);
        }

    }

    // 从ResultSet读取数据时的解密操作（通过列名）
    @Override
    public String getResult(ResultSet rs, String columnName) throws SQLException {
        String encrypted = rs.getString(columnName);
        return encrypted == null ? null : handleDecryption(encrypted);
    }

    // 从ResultSet读取数据时的解密操作（通过列索引）
    @Override
    public String getResult(ResultSet rs, int columnIndex) throws SQLException {
        String encrypted = rs.getString(columnIndex);
        return encrypted == null ? null : handleDecryption(encrypted);
    }

    // 从CallableStatement读取数据时的解密操作（用于存储过程）
    @Override
    public String getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String encrypted = cs.getString(columnIndex);
        return encrypted == null ? null : handleDecryption(encrypted);
    }

    // 处理解密逻辑的方法
    private String handleDecryption(String encrypted) {
        if (encrypted == null) {
            return null;
        }
        try {
            // 尝试解密
            String decrypt = AESUtils.decrypt(DEFAULT_KEY, encrypted);
            // 如果解密返回空，则任务解密失败，直接返回原始数据
            return ToolUtils.isEmpty(decrypt) ? encrypted : decrypt;
        } catch (Exception e) {
            // 如果解密失败，认为该数据未加密，直接返回原始数据
            return encrypted;
        }
    }

}
